package moocloudstudio.minder.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import moocloudstudio.minder.entity.MapShare;
import moocloudstudio.minder.entity.MinderMap;
import moocloudstudio.minder.exception.NotFoundException;
import moocloudstudio.minder.service.MapService;
import moocloudstudio.minder.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.LinkedList;
import java.util.List;

@Api("思维导图处理器")
@RequestMapping("/map")
@RestController
public class MapController {
    @Autowired
    private UserService userService;
    @Autowired
    private MapService mapService;

    @ApiOperation("根据思维导图id查询指定思维导图")
    @GetMapping("/{id}")
    public SaResult getById(@ApiParam("思维导图id") @PathVariable("id") @NotBlank(message = "思维导图id不能为空") String mapId){
        StpUtil.checkLogin();
        MinderMap map = mapService.findAndCheckById(mapId);

        return SaResult.data(map);
    }

    @ApiOperation(value = "保存或修改思维导图", notes = "保存和修改操作都使用此url请求")
    @PostMapping
    public SaResult save(@ApiParam("思维导图") @Validated  MinderMap map) throws Throwable {
        StpUtil.checkLogin();
        String username = userService.findUsernameAndCheckUserById(StpUtil.getLoginIdAsString());

        if (StrUtil.isBlank(map.getUserId())){
            throw new IllegalArgumentException("思维导图用户id不能为空");
        }
        if (! StpUtil.getLoginIdAsString().equals(map.getUserId())){
            throw new RuntimeException("用户无权限修改此思维导图");
        }
        if (StrUtil.isBlank(map.getTitle())){
            throw new IllegalArgumentException("思维导图的标题不能为空");
        }
        if (! StpUtil.getLoginIdAsString().equals(map.getUserId())){
           throw new IllegalArgumentException("思维导图的用户必须为当前用户");
        }

        // 传入新增人或修改人
        boolean isSave = StrUtil.isBlank(map.getId());
        if (isSave){
            map.setCreateBy(username);
        } else {
            map.setUpdateBy(username);
        }
        mapService.save(map);
        return SaResult.data(map);
    }

    @ApiOperation("查询指定用户的思维导图")
    @GetMapping("/list")
    public SaResult list(){
        StpUtil.checkLogin();

        // 清空思维导图data，使前后端数据传输速度更快

        List<MinderMap> maps = new LinkedList<>();
        for (MinderMap tmpMap : mapService.list(StpUtil.getLoginIdAsString())){
            tmpMap.setData("");
            maps.add(tmpMap);
        }
        return SaResult.data(maps);
    }

    @ApiOperation("永久删除指定的思维导图")
    @DeleteMapping("/recycleBin/{id}")
    public SaResult deleteById(@ApiParam("思维导图id") @PathVariable("id") @NotBlank(message = "思维导图id不能为空") String id){
        StpUtil.checkLogin();
        mapService.deleteById(id);
        return SaResult.ok();
    }

    @ApiOperation("逻辑删除指定的思维导图")
    @DeleteMapping("/{id}")
    public SaResult logicDeleteById(@ApiParam("思维导图id") @PathVariable("id") @NotBlank(message = "思维导图id不能为空") String id) throws Throwable {
        StpUtil.checkLogin();
        mapService.logicDeleteById(id);
        // TODO 级联删除分享链接
        return SaResult.ok("删除成功");
    }

    @ApiOperation("根据分享链接id查询思维导图")
    @GetMapping("/share/{shareId}")
    public SaResult getMapByShareId(@ApiParam("分享链接id") @PathVariable("shareId") String shareId){
        // 所有人可访问，不需要身份校验
        MinderMap map = mapService.getAndCheckMapByShareId(shareId);
        if (! map.getMapShare().getShared()){
            throw new NotFoundException("分享链接不存在或已关闭");
        }
        return SaResult.data(map);
    }

    @ApiOperation("开启或关闭分享链接")
    @PutMapping("/share/{shareId}")
    public SaResult updateShared(@ApiParam("分享链接id") @PathVariable("shareId") @NotBlank(message = "分享链接id不能为空") String shareId, @ApiParam("是否开启分享") @NotBlank(message = "是否分享不能为空") Boolean shared){
        StpUtil.checkLogin();
        MinderMap map = mapService.updateShared(shareId, shared, StpUtil.getLoginIdAsString());
        return SaResult.data(map);
    }
}
